﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Torimi.Wiki.Interfaces;
using Torimi.Wiki.DataObjects;

namespace Torimi.Wiki.Services
{
	/// <summary>
	/// A memory based implementation of the Wiki interface.
	/// </summary>
	public class MemoryWiki : IWiki
	{
		private List<WikiPage> _pages;
		private List<Category> _categories;

		public MemoryWiki()
		{
			_pages = new List<WikiPage>();
			_categories = new List<Category>();
		}

		public WikiPage GetPage(Guid id)
		{
			return _pages.Find( p => p.Id == id);
		}

		public WikiPage GetPage(string name)
		{
			return _pages.Find(p => p.Name == name);
		}
		
		public IQueryable<WikiPage> GetAllPages()
		{
			return _pages.AsQueryable();
		}

		public void AddPage(WikiPage page)
		{
			_pages.Add(page);
		}

		public void UpdatePage(WikiPage page)
		{
			DeletePage(page.Id);
			AddPage(page);
		}

		public void DeletePage(Guid id)
		{
			_pages.RemoveAll(p => p.Id == id);
		}

		private IEnumerable<SearchResult> ConvertPagesToSearchResults(IEnumerable<WikiPage> pages)
		{
			var results = new List<SearchResult>();

			foreach (var page in pages)
			{
				int previewLength = Math.Min(50, page.Content.Length);
				results.Add(
					new SearchResult
					{
						Id = page.Id,
						Name = page.Name,
						Title = page.Title,
						Preview = string.Concat(page.Content.Substring(0, previewLength), "...")
					}
				);	
			}

			return results;
		}
		
		IQueryable<SearchResult> IWiki.Search(string keywords, int skip, int take, Category category)
		{
			return ConvertPagesToSearchResults(_pages.FindAll(p => (p.Content.Contains(keywords) || p.Title.Contains(keywords)) ).Skip(skip).Take(take)).AsQueryable();
		}

		public Category GetCategory(Guid id)
		{
			return _categories.Find(c => c.Id == id);
		}

		public void AddCategory(Category category)
		{
			_categories.Add(category);
		}

		public void UpdateCategory(Category category)
		{
			DeleteCategory(category.Id);
			AddCategory(category);
		}

		public void DeleteCategory(Guid id)
		{
			_categories.RemoveAll(c => c.Id == id);
		}

		public IQueryable<Category> GetAllCategories()
		{
			return _categories.AsQueryable();
		}
		
		public void ClearEverything()
		{
			_pages.Clear();
			_categories.Clear();
		}
	}
}
